package fem2d;

import fem2.AbstractStructuralStaticDemo;
import fem2.Element;
import fem2.MaterialModel;
import fem2.MeshPart;
import fem2.Model;
import fem2.StringUtilities;
import fem2.element.StructuralElement;
import fem2.enu.State;
import fem2.material.DruckerPragerMM;
import fem2.material.FluencyCriteria;
import fem2.material.LinearIsotropicHardeningRule;
import fem2.observer.GidPlasticityObserver;
import fem2.observer.TimeStepObserver;
import fem2.strategies.Strategy;

/**
 * slope analysis with normal element and DruckerPrager material
 * 
 * @author hbui
 * 
 */
public class SlopeStabilityDruckerPrager extends SlopeStability {

	public SlopeStabilityDruckerPrager() {
		// meshFileName = "hyplas-mesh.msh"; // 8-node quadrilateral mesh
		// meshFileName = "mesh1.msh"; // 4-node quadrilateral mesh
		// meshFileName = "mesh2.msh"; // 6-node triangle mesh
		// meshFileName = "mesh3.msh"; // 3-node triangle mesh
		meshFileName = "abaqus-mesh-druckerprager.msh"; // 8-node quadrilateral
														// mesh
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 20e6;
		double nu = 0.49;
		double thickness = 1.0;
		State ss = State.PLANE_STRAIN;
		double rho = 0.0;

		/*
		 * approximation of inner edge of Mohr-Coulomb yield surface
		 */
		double phi = (20.0 / 180) * Math.PI;
		double eta = 6 * Math.sin(phi) / Math.sqrt(3) / (3 + Math.sin(phi));
		double xi = 6 * Math.cos(phi) / Math.sqrt(3) / (3 + Math.sin(phi));
		double etabar = eta;// associative flow

		double c = 50e3;
		double H = 0.0;
		FluencyCriteria isoLaw = new LinearIsotropicHardeningRule(c, H);

		return new DruckerPragerMM(E, nu, thickness, rho, ss, eta, etabar, xi, isoLaw);
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		// Element e = new BBarStructuralElement(mp, mm);
		StructuralElement e = new StructuralElement(mp, mm);
		// e.setIntegrationType(IntegrationType.REDUCED_INTEGRATION);
		return e;
	}

	@Override
	public void addObservers(Model m, Strategy s, TimeStepObserver o) {
		super.addObservers(m, s, o);

		String meshName = StringUtilities.getFileName(meshFileName);

		s.addObserver(new GidPlasticityObserver(m, o, projectDir, projectName, meshName));
	}

	// @Override
	// public void run() {
	// Model m = createModel();
	//
	// Analysis an = new LinearStaticAnalysis(m);
	// Strategy s = an.getStrategy();
	// s.setEchoLevel(EchoLevelType.OUTPUT, EchoLevelType.AUX1);
	// s.setTolerance(1e-5);
	//
	// addObservers(m, s, new TimeStepObserver(s));
	//
	// an.run();
	//
	// // postProcess(m);
	//
	// Debugger.warn("Analysis completed");
	// }

	public static void main(String[] args) {
		AbstractStructuralStaticDemo demo = new SlopeStabilityDruckerPrager();

		double[] load_factors = new double[] { 1.0, 2.0, 3.0, 4.0, 4.125, 4.1875, 4.1953125 };

		demo.run(load_factors);
	}
}
